// objecy_json.ts
/*
objecy_json.ts将使用asc编译器生成objecy_json.wasm文件。然后在objecy_json.js代码中调用objecy_json.wasm中的withInputAndOutput()函数。
在objecy_json.js代码中，声明了一个学生对象object，然将学生信息对象序列化为 JSON 字符串并写入 WebAssembly 内存
序列化返回的地址指针，将输入到withInputAndOutput()函数中。

在withInputAndOutput()函数中，通过输入的地址指针，反序列化内存数据。在withInputAndOutput()函数内修改对象的值。
最后在然将学生信息对象序列化为 JSON 字符串并写入 WebAssembly 内存。返回指针到object_json.js代码中。


*/
// 定义学生信息结构
// 定义学生信息结构
class StudentInfo {
    id: u32;
    name: string;
    age: u32;
    grade: u32;
    time: f64;

    constructor(id: u32, name: string, age: u32, grade: u32, time: f64) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.grade = grade;
        this.time = time;
    }

    // 手动实现序列化，将对象转为 JSON 字符串并存储到内存
    static serialize(ptr: usize, student: StudentInfo): void {
        const jsonString = `{"id":${student.id},"name":"${student.name}","age":${student.age},"grade":${student.grade},"time":${student.time}}`;
        const len = jsonString.length; // JSON 字符串长度
    
        // 将 JSON 字符串逐字符写入内存
        for (let i = 0; i < len; i++) {
            store<u8>(ptr + i, jsonString.charCodeAt(i));
        }
        store<u8>(ptr + len, 0); // 终止符
    }
    

    // 手动实现反序列化，从内存读取 JSON 字符串并解析为对象
    static deserialize(ptr: usize): StudentInfo {
        let jsonString = "";
        let offset = 0;
        while (true) {
            let charCode = load<u8>(ptr + offset);
            if (charCode == 0) break; // 遇到终止符时停止
            jsonString += String.fromCharCode(charCode);
            offset++;
        }

        // 手动解析 JSON 字符串
        let id = 0;
        let name = "";
        let age = 0;
        let grade = 0;
        let time = 0.0;

        // 去掉外层花括号并按逗号分割
        let content = jsonString.slice(1, jsonString.length - 1); // 去掉首尾的 { 和 }
        let parts = content.split(",");

        for (let i = 0; i < parts.length; i++) {
            let pair = parts[i].split(":");
            let key = pair[0].trim(); // 直接去掉多余的空格
            let value = pair[1].trim();

            // 去掉 key 和 value 两边的引号
            key = key.startsWith('"') && key.endsWith('"') ? key.slice(1, key.length - 1) : key;
            value = value.startsWith('"') && value.endsWith('"') ? value.slice(1, value.length - 1) : value;

            // 根据 key 值解析对应的字段
            if (key == "id") id = <u32>parseInt(value);
            else if (key == "name") name = value;
            else if (key == "age") age = <u32>parseInt(value);
            else if (key == "grade") grade = <u32>parseInt(value);
            else if (key == "time") time = parseFloat(value);
        }

        return new StudentInfo(id, name, age, grade, time);
    }

}

// 导出函数
export function withInputAndOutput(inputStudentPtr: usize): usize {
    // 读取传入的学生信息
    const startTime1 = performance.now();
    const inputStudent = StudentInfo.deserialize(inputStudentPtr);
    const endTime1 = performance.now();
    const inputTime = endTime1 - startTime1;
    // 修改学生对象
    inputStudent.id += 1;
    inputStudent.time = inputTime;

    // 将修改后的学生对象写回内存
    StudentInfo.serialize(inputStudentPtr, inputStudent);

    // 返回输入的指针，表示修改已经完成
    return inputStudentPtr;
}
